package com.rzjm.api.netty.water;

import com.rzjm.api.netty.water.constant.ResultCodeEnum;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPromise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

public class CommandSender {
    private static final Logger LOGGER = LoggerFactory.getLogger(CommandSender.class);


    /**
     * 发送异步命令
     *
     * @param deviceId  设备ID
     * @param message   下发的命令报文
     * @return 响应结果，格式{"resultCode":0, "message":"成功"}
     * 具体错误描述见{@link ResponseData}
     */
    public static ResponseData sentAsyncCommand(Integer deviceId, String message) {
        Channel channel = NettyUtil.getChannel(deviceId);
        if (channel == null) {
            return ResponseData.getInstance(ResultCodeEnum.NOT_ONLINE.getCode(), ResultCodeEnum.NOT_ONLINE.getDescription());
        }
        channel.writeAndFlush(message);
        LOGGER.info("发送异步命令message={} time = {}",message, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +": 发送异步命令 : " + message);

        return ResponseData.getInstance(ResultCodeEnum.OK.getCode(), ResultCodeEnum.OK.getDescription());
    }

	/**
	 * 发送异步命令
	 *
	 * @param deviceId  设备ID
	 * @param message   下发的命令报文
	 * @return 响应结果，格式{"resultCode":0, "message":"成功"}
	 * 具体错误描述见{@link ResponseData}
	 */
	public static ResponseData sentAsyncCommand(Integer deviceId, Object message) {
		Channel channel = NettyUtil.getChannel(deviceId);
		if (channel == null) {
			return ResponseData.getInstance(ResultCodeEnum.NOT_ONLINE.getCode(), ResultCodeEnum.NOT_ONLINE.getDescription());
		}
		channel.writeAndFlush(message);
		LOGGER.info("发送异步命令message={} time = {}",message, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//		System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +": 发送异步命令 : " + message);

		return ResponseData.getInstance(ResultCodeEnum.OK.getCode(), ResultCodeEnum.OK.getDescription());
	}


    /**
     * 发送同步命令
     *
     * @param deviceId
     * @param message         发的命令报文
     * @param tag            报文服务序号
     * @return
     */
    public static ResponseData sentSyncCommand(int deviceId,  int tag, String message) {
        //超时时间，单位毫秒
        int timeout = 15;

        return sentSyncCommand(deviceId, tag, message, timeout);
    }

    /**
     * 发送同步命令
     *
     * @param deviceId             设备ID
     * @param message              下发的命令报文
     * @param tag                  报文服务序号
     * @param timeout              超时时间，单位毫秒
     * @return
     */
    public static ResponseData sentSyncCommand(int deviceId, long tag, String message, int timeout) {

        Channel channel = NettyUtil.getChannel(deviceId);
        if (channel == null) {
            return ResponseData.getInstance(ResultCodeEnum.NOT_ONLINE.getCode(), ResultCodeEnum.NOT_ONLINE.getDescription());
        }
        //默认是超时状态，后续收到设备返回值，会设置为成功。
        ResponseData responseData = ResponseData.getInstance(ResultCodeEnum.OUT_TIME_ERROR.getCode(), ResultCodeEnum.OUT_TIME_ERROR.getDescription());
        try {
            LOGGER.info(" 请求参数 tag: " + tag);
            NettyUtil.SYNC_RESPONSEDATA_MAP.put(tag, responseData);

            LOGGER.info(" 请求参数 获取 tag: " + NettyUtil.SYNC_RESPONSEDATA_MAP.get(tag).toString());

            ChannelPromise promise = NettyUtil.getChannelPromise(deviceId);
            if (promise != null) {
                responseData.setPromise(promise);
                channel.writeAndFlush(message);
                LOGGER.info("发送同步命令 tag={} message={} time = {}", tag, message, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//                System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +": 发送同步命令 : " + message);
                LOGGER.info("超时时间： " + timeout);
                promise.await(timeout, TimeUnit.MILLISECONDS);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            LOGGER.info(" tag 被移除： ");
            NettyUtil.SYNC_RESPONSEDATA_MAP.remove(tag);
        }
        return responseData;
    }


}
